package nc.impl.hrppl.proupdate.proupdatehvo;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import nc.bs.dao.BaseDAO;
import nc.bs.util.DefdocUtils;
import nc.itf.hrppl.proupdate.proupdatehvo.IProUpdateHVOCheckService;
import nc.jdbc.framework.processor.MapProcessor;
import nc.vo.hrppl.proupdate.AggProUpdateHVO;
import nc.vo.hrppl.proupdate.CGUpdateCVO;
import nc.vo.hrppl.proupdate.ProUpdateBVO;
import nc.vo.hrppl.proupdate.ProUpdateCVO;
import nc.vo.hrppl.proupdate.ProUpdateHVO;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFDouble;

public class ProUpdateHVOCheckServiceImpl implements IProUpdateHVOCheckService {
	private BaseDAO dao;

	@SuppressWarnings("unchecked")
	@Override
	public AggProUpdateHVO[] checkNotUpdateAggProUpdateHVO(AggProUpdateHVO[] aggvos) throws BusinessException {
		if (aggvos == null)
			return null;
		try {
			List<Map<String, Object>> listdefs = DefdocUtils.getDefdoc("XMSQ_XMTZ_0001");
			if (listdefs == null || listdefs.isEmpty())
				return aggvos;
			AggProUpdateHVO aggvo = aggvos[0];
			ProUpdateHVO hvo = aggvo.getParentVO();
			String pk_project = hvo.getPk_proapp();
			Map<String, Map<String, Object>> mapsql = this.handlerDefdoc(listdefs, pk_project);
			if (!this.queryIsProUpdate(aggvo, listdefs, mapsql, pk_project)) {
				throw new BusinessException("当前单据项目未进行调整，不允许保存!");
			}

		} catch (BusinessException e) {
			throw new BusinessException(e);
		}
		return aggvos;
	}

	/**
	 * 
	 * @param listdefs   需要校验的所有字段
	 * @param pk_project 项目编码
	 * @param h          表头校验字段个数
	 * @param zj         资金页签校验字段个数
	 * @param jx         绩效页签校验字段个数
	 * @param cg         采购页签校验字段个数
	 * @return
	 * @throws BusinessException
	 */
	protected Map<String, Map<String, Object>> handlerDefdoc(List<Map<String, Object>> listdefs, String pk_project)
			throws BusinessException {
		Map<String, Map<String, Object>> mapsqls = new HashMap<String, Map<String, Object>>();
		StringBuilder hsql = new StringBuilder();
		StringBuilder zjsql = new StringBuilder();
		StringBuilder jxsql = new StringBuilder();
		StringBuilder cgsql = new StringBuilder();
		int h = 0, zj = 0, jx = 0, cg = 0;
		for (Map map : listdefs) {
			if ("h".equals(map.get("def1"))) {
				h++;
				if (hsql.toString().length() == 0) {
					hsql.append("select  " + map.get("code") + " ");
				} else {
					hsql.append(" ," + map.get("code") + " ");
				}
			} else if ("zj".equals(map.get("def1"))) {
				zj++;
				if (zjsql.toString().length() == 0) {
					zjsql.append("select  " + map.get("code") + " ");
				} else {
					zjsql.append(" ," + map.get("code") + " ");
				}

			} else if ("jx".equals(map.get("def1"))) {
				jx++;
				if (jxsql.toString().length() == 0) {
					jxsql.append("select  " + map.get("code") + " ");
				} else {
					jxsql.append(" ," + map.get("code") + " ");
				}

			} else if ("cg".equals(map.get("def1"))) {
				cg++;
				if (cgsql.toString().length() == 0) {
					cgsql.append("select  " + map.get("code") + " ");
				} else {
					cgsql.append(" ," + map.get("code") + " ");
				}

			}
		}
		if (h > Integer.valueOf(0)) {
			Map<String, Object> hmap = new HashMap<String, Object>();
			hsql.append("  from hrppl_pjappl  ");
			hsql.append("  where 1 = 1 ");
			hsql.append("    and pk_pjappl = '" + pk_project + "'");
			hmap.put("sql", hsql.toString());
			hmap.put("h", hsql.toString());
			mapsqls.put("hsql", hmap);
		}
		if (zj > Integer.valueOf(0)) {
			Map<String, Object> zjmap = new HashMap<String, Object>();
			zjsql.append("  from hrppl_pjappl_b  ");
			zjsql.append("  where 1 = 1 ");
			zjsql.append("    and pk_pjappl = '" + pk_project + "'");
			zjmap.put("sql", zjsql.toString());
			zjmap.put("zj", zj);
			mapsqls.put("zjsql", zjmap);
		}
		if (jx > Integer.valueOf(0)) {
			Map<String, Object> jxmap = new HashMap<String, Object>();
			jxsql.append("  from hrppl_pjappl_c  ");
			jxsql.append("  where 1 = 1 ");
			jxsql.append("    and pk_pjappl = '" + pk_project + "'");
			jxmap.put("sql", jxsql.toString());
			jxmap.put("jx", jx);
			mapsqls.put("jxsql", jxmap);
		}
		if (cg > Integer.valueOf(0)) {
			Map<String, Object> cgmap = new HashMap<String, Object>();
			cgsql.append("  from hrppl_pjappl_p  ");
			cgsql.append("  where 1 = 1 ");
			cgsql.append("    and pk_pjappl = '" + pk_project + "'");
			cgmap.put("sql", cgsql);
			cgmap.put("cg", cg);
			mapsqls.put("cgsql", cgmap);
		}
		return mapsqls;
	}

	/**
	 * 是否存在项目调整
	 * 
	 * @param aggvo      调整单aggvo
	 * @param listdefs   需要校验的字段
	 * @param mapsql     需要校验的申请单sql，需要校验的字段个数
	 * @param pk_project 需要调整的项目主键
	 * @return true: 是调整  、 false:未调整
	 * @throws BusinessException
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	protected Boolean queryIsProUpdate(AggProUpdateHVO aggvo, List<Map<String, Object>> listdefs,
			Map<String, Map<String, Object>> mapsql, String pk_project) throws BusinessException {
		Boolean h_flag = false, zj_flag = false, jx_flag = false, cg_flag= false; // 申请单是否为修改
		ProUpdateHVO hvo = aggvo.getParentVO();
		Map<String, Object> map = mapsql.get("hsql");
		if(map != null && !map.isEmpty()) {
			Object sql = map.get("sql");
			Map<String, Object> hmap = (Map<String, Object>)this.getDao().executeQuery(sql.toString(), new MapProcessor());
			if(hmap != null && !hmap.isEmpty()) {
				for (Map listmap : listdefs) {
					if("h".equals(listmap.get("def1"))) {
						Object sqdatt = hmap.get(listmap.get("code") + "");
						if(sqdatt instanceof BigDecimal) {
							UFDouble val = new UFDouble((BigDecimal) sqdatt);
							UFDouble ufDouble = new UFDouble(hvo.getAttributeValue(listmap.get("shortname") + "")+"");
							Boolean falg = val.sub(ufDouble).getDouble() != new Double(0);
							if(falg) {
								h_flag = true;
								break;
							}
						}else if( sqdatt instanceof Integer) {
							UFDouble val = new UFDouble((BigDecimal) sqdatt);
							UFDouble ufDouble = new UFDouble(hvo.getAttributeValue(listmap.get("shortname") + "")+"");
							Boolean falg = val.sub(ufDouble).getDouble() != new Double(0);
							if(falg) {
								h_flag = true;
								break;
							}
						}else {
							if ( !(hmap.get(listmap.get("code") + "")+"").equals(hvo.getAttributeValue(listmap.get("shortname") + "")+"")) {
								h_flag = true;
								break;
							}
						}
						
					}
					
				}
			}
		}
		Map<String, Object> zjmap = mapsql.get("zjsql");
		if(zjmap != null && !zjmap.isEmpty()) {
			ProUpdateBVO[] zjvos = (ProUpdateBVO[])aggvo.getChildren(ProUpdateBVO.class);
			if(zjvos != null ) {
				for(ProUpdateBVO zjvo : zjvos) {
					if(zj_flag) break;
					String sql =  zjmap.get("sql")+" and rowno = " + zjvo.getRowno();
					Map<String, Object> sqdzj = (Map<String, Object>)this.getDao().executeQuery(sql, new MapProcessor());
					if(sqdzj != null) {
						for (Map listmap : listdefs) {
							if("zj".equals(listmap.get("def1")) ) {
								Object obj = sqdzj.get(listmap.get("code") + "");
								if(obj instanceof BigDecimal) {
									UFDouble val = new UFDouble((BigDecimal) obj);
									UFDouble ufDouble = new UFDouble(zjvo.getAttributeValue(listmap.get("shortname") + "")+"");
									Boolean falg = val.sub(ufDouble).getDouble() != new Double(0);
									if(falg) {
										zj_flag = true;
										break;
									}
								}else if( obj instanceof Integer) {
									UFDouble val = new UFDouble((BigDecimal) obj);
									UFDouble ufDouble = new UFDouble(zjvo.getAttributeValue(listmap.get("shortname") + "")+"");
									Boolean falg = val.sub(ufDouble).getDouble() != new Double(0);
									if(falg) {
										zj_flag = true;
										break;
									}
								}else {
									if (!(sqdzj.get(listmap.get("code") + "")+"").equals(zjvo.getAttributeValue(listmap.get("shortname") + "")+"")) {
										zj_flag = true;
										break;
									}
								}
								
							}
							
						}
					}else {
						zj_flag = true;
						break;
					}
				}
				
			}
		}

		Map<String, Object> jxmap = mapsql.get("jxsql");
		if(jxmap != null && !jxmap.isEmpty()) {
			ProUpdateCVO[] jxvos = (ProUpdateCVO[])aggvo.getChildren(ProUpdateCVO.class);
			if(jxvos != null ) {
				for(ProUpdateCVO jxvo : jxvos) {
					if(jx_flag) break;
					String sql =  jxmap.get("sql")+" and rowno = " + jxvo.getRowno();
					Map<String, Object> sqdzj = (Map<String, Object>)this.getDao().executeQuery(sql, new MapProcessor());
					if(sqdzj != null) {
						for (Map listmap : listdefs) {
							if("jx".equals(listmap.get("def1"))) {
								Object obj = sqdzj.get(listmap.get("code") + "");
								if(obj instanceof BigDecimal) {
									UFDouble val = new UFDouble((BigDecimal) obj);
									UFDouble ufDouble = new UFDouble(jxvo.getAttributeValue(listmap.get("shortname") + "")+"");
									Boolean falg = val.sub(ufDouble).getDouble() != new Double(0);
									if(falg) {
										jx_flag = true;
										break;
									}
								}else if( obj instanceof Integer) {
									UFDouble val = new UFDouble((BigDecimal) obj);
									UFDouble ufDouble = new UFDouble(jxvo.getAttributeValue(listmap.get("shortname") + "")+"");
									Boolean falg = val.sub(ufDouble).getDouble() != new Double(0);
									if(falg) {
										jx_flag = true;
										break;
									}
								}else {
									if (!(sqdzj.get(listmap.get("code") + "")+"").equals(jxvo.getAttributeValue(listmap.get("shortname") + "")+"")) {
										jx_flag = true;
										break;
									}
								}
								
							}
						}
					}else {
						jx_flag = true;
						break;
					}
				}
			}
		}

		Map<String, Object> cgmap = mapsql.get("cgsql");
		if(cgmap != null && !cgmap.isEmpty()) {
			CGUpdateCVO[] cgvos = (CGUpdateCVO[])aggvo.getChildren(CGUpdateCVO.class);
			if(cgvos != null ) {
				for(CGUpdateCVO cgvo : cgvos) {
					if(cg_flag) break;
					String sql =  cgmap.get("sql")+" and rowno = " + cgvo.getRowno();
					Map<String, Object> sqdzj = (Map<String, Object>)this.getDao().executeQuery(sql, new MapProcessor());
					if(sqdzj != null) {
						for (Map listmap : listdefs) {
							if("cg".equals(listmap.get("def1"))) {
								Object obj = sqdzj.get(listmap.get("code") + "");
								if(obj instanceof BigDecimal) {
									UFDouble val = new UFDouble((BigDecimal) obj);
									UFDouble ufDouble = new UFDouble(cgvo.getAttributeValue(listmap.get("shortname") + "")+"");
									Boolean falg = val.sub(ufDouble).getDouble() != new Double(0);
									if(falg) {
										cg_flag = true;
										break;
									}
								}else if( obj instanceof Integer) {
									UFDouble val = new UFDouble((BigDecimal) obj);
									UFDouble ufDouble = new UFDouble(cgvo.getAttributeValue(listmap.get("shortname") + "")+"");
									Boolean falg = val.sub(ufDouble).getDouble() != new Double(0);
									if(falg) {
										cg_flag = true;
										break;
									}
								}else {
									if ( !sqdzj.get(listmap.get("code") + "").equals(cgvo.getAttributeValue(listmap.get("shortname") + "")+"")) {
										cg_flag = true;
										break;
									}
								}
								
							}
						
						}
					}else {
						cg_flag = true;
						break;
					}
				}
			}
		}
        // 其中一个ture 说明有修改
        return h_flag || zj_flag || jx_flag || cg_flag;
    }

	protected UFDouble toDouble(Object obj) {
        UFDouble val;
        if (obj instanceof BigDecimal) {
            val = new UFDouble((BigDecimal) obj);
        } else if (obj instanceof Integer) {
            val = new UFDouble((Integer) obj);
        } else {
            val = UFDouble.ZERO_DBL;
        }
        return val;
	}
	
	public BaseDAO getDao() {
		return dao == null ? new BaseDAO() : dao;
	}

}
